package com.blankii.androidlibrary.utils

import android.app.Activity
import android.graphics.Point
import android.os.Build
import android.util.DisplayMetrics
import com.blankii.androidlibrary.exts.logd
import com.blankii.androidlibrary.utils.VersionUtils.isAndroid11
import java.util.UUID
import kotlin.math.pow
import kotlin.math.sqrt


/**
 * author: blankii
 * created on: 2024/4/29 10:22
 * description:
 */
object HardwareInfoUtil {
    private val TAG: String = "HardwareInfo"
    const val standardWith = 800
    const val standardHeight = 1280
    // 获取屏幕的默认分辨率
    fun getDisplayWidth(activity: Activity): Int {
        var result = 0
        if (isAndroid11()) {
            result = activity.windowManager.currentWindowMetrics.bounds.width()//算上状态栏的高度了
        } else {
            val point = Point()
            activity.windowManager.defaultDisplay.getRealSize(point)
            result = point.x
        }
        return result
    }

    fun getDisplayHeight(activity: Activity): Int {
        var result = 0
        if (isAndroid11()) {
            result = activity.windowManager.currentWindowMetrics.bounds.height()
        } else {
            val point = Point()
            activity.windowManager.defaultDisplay.getRealSize(point)
            result = point.y
        }
        return result
    }


    fun getInch(activity: Activity): Float {/* 获取屏幕信息 */
        val dm: DisplayMetrics = activity.resources.displayMetrics
        val renderY = getDisplayHeight(activity)
        val renderX = getDisplayWidth(activity)/* 物理分辨率（英寸） */
        // 渲染比例（每英寸像素）
        val dpiX: Float = dm.xdpi
        val dpiY: Float = dm.ydpi
        // 物理尺寸 = 渲染尺寸 / 渲染比例
        val physicalX: Float = renderX / dpiY
        val physicalY = renderY / dpiX/* 屏幕尺寸（对角线长度） */
        // 物理宽高，勾股定理，对角线物理长度
        return sqrt(physicalX.pow(2.0f) + physicalY.pow(2.0f))
    }

    fun getPPi(activity: Activity): Int {
        val number: Int =
            (getDisplayWidth(activity).toFloat().pow(2f) + getDisplayHeight(activity).toFloat()
                .pow(2f)).toInt()
        return (sqrt(number.toDouble()) / getInch(activity)).toInt()
    }

    /**
     * 1 屏幕密度:（宽²+高²）开根号/英寸
     * 在Android中，规定以160dpi（即屏幕分辨率为320x480）为基准：1dp=1px
     */
    fun getDpiString(activity: Activity): String {
        val ppi = getPPi(activity)
        var result = ""
        when (ppi) {
            in 0..140 -> {
                result = "ldpi/0.75"
            }

            in 140..186 -> {
                result = "mdpi/1"
            }

            in 186..226 -> {
                result = "tvdpi/1.33"
            }

            in 226..280 -> {
                result = "hdpi/1.5"
            }

            in 280..400 -> {
                result = "xhdpi/2"
            }

            in 400..560 -> {
                result = "xxhdpi/3"
            }

            in 560..640 -> {
                result = "xxxhdpi/4"
            }

            else -> {
                result = "others"
            }
        }
        return result
    }

    fun getDpiNum(activity: Activity): Double {
        val dpiString = getDpiString(activity)
        val numString = dpiString.substring(dpiString.indexOf("/") + 1, dpiString.length)
        numString.logd(TAG)
        return numString.toDouble()
    }

    fun getCanvasRadio(activity: Activity): Double {
        val width = getDisplayWidth(activity)
        val height = getDisplayHeight(activity)
        val valueWidth: Double = width.toDouble() / standardWith
        val valueHeight: Double = height.toDouble() / standardHeight
        val value = valueHeight + valueWidth
        return sqrt(value)
    }

    /**
     * 获取Android-id
     * ANDROID_ID的获取门槛是最低的，不需要任何权限，
     * 但ANDROID_ID也存在一些缺点，就是无法保证稳定性，root、
     * 刷机或恢复出厂设置都会导致设备的ANDROID_ID发生改变。
     * 此外，我看到部分文章中有提到某些厂商定制系统的Bug会导致不同的设备可能会产生相同的ANDROID_ID，
     * 而且某些设备获取到的ANDROID_ID为null。
     * 如果应用对于设备标识的要求不是特别高的话还是一个值得考虑的方案。
     */
//    @SuppressLint("HardwareIds")
//    fun getAndroidId(context: Context): String {
//        val telephonyMgr = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
//        var imei: String = ""
//        if (VersionUtils.isAndroid8()) {
//            imei = telephonyMgr.imei
//        } else {
//            imei = telephonyMgr.deviceId
//        }
//        return imei
//    }

    fun getAndroidId(): String {
        var serial: String? = null
        val m_szDevIDShort =
            "35" + Build.BOARD.length % 10 + Build.BRAND.length % 10 + (if (null != Build.CPU_ABI) Build.CPU_ABI.length else 0) % 10 + Build.DEVICE.length % 10 + Build.DISPLAY.length % 10 + Build.HOST.length % 10 + Build.ID.length % 10 + Build.MANUFACTURER.length % 10 + Build.MODEL.length % 10 + Build.PRODUCT.length % 10 + Build.TAGS.length % 10 + Build.TYPE.length % 10 + Build.USER.length % 10 //13 位
        if (Build.VERSION.SDK_INT <= 29) {
            try {
                serial = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    Build.getSerial()
                } else {
                    Build.SERIAL
                }
                //API>=9 使用serial号
                return UUID(
                    m_szDevIDShort.hashCode().toLong(), serial.hashCode().toLong()
                ).toString()
            } catch (exception: java.lang.Exception) {
                serial = "serial" // 随便一个初始化
            }
        } else {
            serial = Build.UNKNOWN // 随便一个初始化
        }

        //使用硬件信息拼凑出来的15位号码
        return UUID(m_szDevIDShort.hashCode().toLong(), serial.hashCode().toLong()).toString()
    }
}